home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-01-16 | 10.2 KB | 558 lines | [TEXT/MPS ] |
- /*********************************************************************
- Project : GUSI - Grand Unified Socket Interface
- File : GUSIFSp.cp - Dealing with paths
- Author : Matthias Neeracher <neeri@iis.ethz.ch>
- Started : 15Jun92 Language : MPW C++
- 06Sep92 MN Clear ioACUser
- 12Sep92 MN Renamed Paths.h to GUSIFSp_P.h
- 15Nov92 MN Forgot a few consts
- 15Nov92 MN Rename GUSIFSp_P.h to TFileSpec.h (there we go again)
- 15Jan93 MN IsParentOf
- Last : 15Jan93
- *********************************************************************/
-
- #include "GUSI_P.h"
- #include "TFileSpec.h"
-
- #include <Errors.h>
- #include <Memory.h>
- #include <Aliases.h>
- #include <string.h>
- #include <ioctl.h>
- #include <fcntl.h>
- #include <errno.h>
-
- OSErr TFileSpec::error;
- short TFileSpec::curVol;
- long TFileSpec::curDir = -1;
-
- OSErr TFileSpec::ChDir(const TFileSpec & spec)
- {
- TFileSpec nudir(spec);
-
- nudir += "\p";
-
- if (error)
- return error;
-
- curVol = nudir.vRefNum;
- curDir = nudir.parID;
-
- return noErr;
- }
-
- static OSErr CurrentDir(short & vRefNum, long & parID)
- {
- OSErr error;
- WDPBRec vol;
- Str63 name;
-
- vol.ioNamePtr = name;
-
- if (error = PBHGetVolSync(&vol))
- return error;
-
- vRefNum = vol.ioWDVRefNum;
- parID = vol.ioWDDirID;
-
- return noErr;
- }
-
- OSErr TFileSpec::Default()
- {
- if (curDir != -1) {
- vRefNum = curVol;
- parID = curDir;
- } else if (error = CurrentDir(vRefNum, parID))
- return error;
-
- --*this;
-
- return error;
- }
-
- TFileSpec::TFileSpec(const FSSpec & spec, Boolean useAlias)
- : FSSpec(spec)
- {
- if (!useAlias && hasAlias)
- Resolve();
- }
-
- TFileSpec::TFileSpec(short vRefNum, long parID, ConstStr31Param name, Boolean useAlias)
- {
- this->vRefNum = vRefNum;
- this->parID = parID;
- memcpy(this->name, name, *name+1);
-
- if (!useAlias && hasAlias)
- Resolve();
- }
-
- TFileSpec::TFileSpec(short wd, ConstStr31Param name, Boolean useAlias)
- {
- WDPBRec wdPB;
-
- wdPB.ioNamePtr = nil;
- wdPB.ioVRefNum = wd;
- wdPB.ioWDIndex = 0;
- wdPB.ioWDProcID = 0;
-
- /* Change the Working Directory number in vRefnum into a real vRefnum */
- /* and DirID. The real vRefnum is returned in ioVRefnum, and the real */
- /* DirID is returned in ioWDDirID. */
-
- if (error = PBGetWDInfoSync(&wdPB))
- return;
-
- vRefNum = wdPB.ioWDVRefNum;
- parID = wdPB.ioWDDirID;
- memcpy(this->name, name, *name+1);
-
- if (!useAlias && hasAlias)
- Resolve();
- }
-
- #define maxPathLen 512
-
- static char fullPath[maxPathLen];
-
- /* Convert an FSSpec into a full pathname. The pathname is accumulated on the
- high end of path to avoid excessive copying.
- */
-
- char * TFileSpec::FullPath() const
- {
- CInfoPBRec block;
- char * curPath;
-
- /* Special case: a volume was specified */
- if (parID == fsRtParID) {
- memcpy(fullPath, name+1, *name);
- curPath = fullPath+*name;
- curPath[0] = ':';
- curPath[1] = 0;
- error = noErr;
-
- return fullPath;
- }
-
- fullPath[maxPathLen-1] = 0;
- curPath = fullPath+maxPathLen-*name-1;
-
- memcpy(curPath, name+1, *name);
-
- block.dirInfo.ioNamePtr = (StringPtr) fullPath;
- block.dirInfo.ioDrParID = parID;
-
- do {
- block.dirInfo.ioVRefNum = vRefNum;
- block.dirInfo.ioFDirIndex = -1;
- block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
-
- if (error = PBGetCatInfoSync(&block))
- return "";
- *--curPath = ':';
- curPath -= *fullPath;
- memmove(curPath, fullPath+1, *fullPath);
- } while (block.dirInfo.ioDrDirID != fsRtDirID);
-
- return curPath;
- }
-
- char * TFileSpec::RelPath() const
- {
- short curVRef;
- long curDirID;
- CInfoPBRec block;
- char * curPath;
-
- if (error = CurrentDir(curVRef, curDirID))
- return "";
-
- /* Special case: a volume was specified */
- if (parID == fsRtParID) {
- if (vRefNum == curVRef && curDirID == fsRtDirID)
- curPath = fullPath;
- else {
- memcpy(fullPath, name+1, *name);
- curPath = fullPath+*name;
- }
-
- curPath[0] = ':';
- curPath[1] = 0;
-
- return fullPath;
- }
-
- block.dirInfo.ioNamePtr = (StringPtr)fullPath;
- block.dirInfo.ioVRefNum = curVRef;
- block.dirInfo.ioFDirIndex = -1;
- block.dirInfo.ioDrDirID = curDirID;
-
- if (error = PBGetCatInfoSync(&block))
- return "";
-
- if (curVRef == vRefNum
- && block.dirInfo.ioDrParID == parID
- && !memcmp (fullPath, name, *fullPath+1)
- ) {
- fullPath[0] = ':';
- fullPath[1] = 0;
-
- return fullPath;
- }
-
- fullPath[maxPathLen-1] = 0;
- curPath = fullPath+maxPathLen-*name-1;
-
- memcpy(curPath, name+1, *name);
-
- block.dirInfo.ioNamePtr = (StringPtr) fullPath;
- block.dirInfo.ioDrParID = parID;
-
- do {
- *--curPath = ':';
-
- /* Test fur current directory */
- if (curVRef == vRefNum && curDirID == block.dirInfo.ioDrParID)
- return strchr(curPath+1, ':') ? curPath : curPath+1;
-
- block.dirInfo.ioVRefNum = vRefNum;
- block.dirInfo.ioFDirIndex = -1;
- block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
-
- if (error = PBGetCatInfoSync(&block))
- return "";
- curPath -= *fullPath;
- memmove(curPath, fullPath+1, *fullPath);
- } while (block.dirInfo.ioDrDirID != fsRtDirID);
-
- return curPath;
- }
-
- OSErr TFileSpec::CatInfo(CInfoPBRec & info, Boolean dirInfo) const
- {
- info.dirInfo.ioVRefNum = vRefNum;
- info.dirInfo.ioDrDirID = parID;
- info.dirInfo.ioNamePtr = name;
- info.dirInfo.ioFDirIndex = dirInfo ? -1 : 0;
- #ifdef OnceThisFieldIsDefined
- info.dirInfo.ioACUser = 0;
- #else
- info.dirInfo.filler2 = 0;
- #endif
-
- return error = PBGetCatInfoSync(&info);
- }
-
- TFileSpec TFileSpec::operator--()
- {
- CInfoPBRec cb;
-
- CatInfo(cb, true);
-
- if (!error)
- parID = cb.dirInfo.ioDrParID;
-
- return *this;
- }
-
- TFileSpec TFileSpec::operator-=(int levels)
- {
- while (levels-- > 0) {
- --*this;
- if (this->Error())
- break;
- }
-
- return *this;
- }
-
- TFileSpec TFileSpec::operator-(int levels) const
- {
- TFileSpec spec = *this;
-
- return spec -= levels;
- }
-
- inline OSErr TFileSpec::Resolve(const CInfoPBRec & info)
- {
- Boolean isFolder;
- Boolean wasAlias;
-
- return error =
- (hasAlias && IsAlias(info)) ?
- ResolveAliasFile(this, true, &isFolder, &wasAlias) :
- noErr;
- }
-
- OSErr TFileSpec::Resolve(Boolean gently)
- {
- CInfoPBRec ourinfo;
-
- CatInfo(ourinfo);
-
- if (error)
- if (gently)
- return error = noErr;
- else
- return error;
- else
- return Resolve(ourinfo);
- }
-
- Boolean TFileSpec::Exists() const
- {
- Boolean res;
- CInfoPBRec ourinfo;
-
- res = !CatInfo(ourinfo);
- error = noErr;
-
- return res;
- }
-
- Boolean TFileSpec::operator==(const TFileSpec & other) const
- {
- return vRefNum == other.vRefNum
- && parID == other.parID
- && EqualString(name, other.name, false, true);
- }
-
- Boolean TFileSpec::operator!=(const TFileSpec & other) const
- {
- return vRefNum != other.vRefNum
- || parID != other.parID
- || !EqualString(name, other.name, false, true);
- }
-
- Boolean TFileSpec::IsParentOf(const TFileSpec & other) const
- {
- for (TFileSpec oth = other - 1; !oth.Error() && *this != oth; --oth);
-
- return !oth.Error();
- }
-
- TFileSpec TFileSpec::operator+=(ConstStr31Param name)
- {
- CInfoPBRec cb;
-
- if (CatInfo(cb))
- goto punt;
-
- // Resolve if an alias
-
- if (IsAlias(cb))
- if (Resolve(cb) || CatInfo(cb))
- goto punt;
-
- if (IsFile(cb)) {
- error = bdNamErr;
-
- goto punt;
- }
-
- parID = cb.dirInfo.ioDrDirID;
-
- memcpy(this->name, name, *name+1);
-
- punt:
- return *this;
- }
-
- TFileSpec TFileSpec::operator+(ConstStr31Param name) const
- {
- TFileSpec spec = *this;
-
- return spec += name;
- }
-
- TFileSpec TFileSpec::operator+=(const char * name)
- {
- CInfoPBRec cb;
-
- if (CatInfo(cb))
- goto punt;
-
- // Resolve if an alias
-
- if (IsAlias(cb))
- if (Resolve(cb) || CatInfo(cb))
- goto punt;
-
- if (IsFile(cb)) {
- error = bdNamErr;
-
- goto punt;
- }
-
- if (IsFile(cb)) {
- error = bdNamErr;
-
- goto punt;
- }
-
- parID = cb.dirInfo.ioDrDirID;
-
- memcpy(this->name+1, name, *this->name = strlen(name));
-
- punt:
- return *this;
- }
-
- TFileSpec TFileSpec::operator+(const char * name) const
- {
- TFileSpec spec = *this;
-
- return spec += name;
- }
-
- TFileSpec TFileSpec::operator[](short index) const
- {
- TFileSpec spec = *this;
- CInfoPBRec cb;
-
- cb.dirInfo.ioVRefNum = spec.vRefNum;
- cb.dirInfo.ioDrDirID = spec.parID;
- cb.dirInfo.ioNamePtr = spec.name;
- cb.dirInfo.ioFDirIndex = index;
-
- error = PBGetCatInfoSync(&cb);
-
- return spec;
- }
-
- TFileSpec::TFileSpec(const char * path, Boolean useAlias)
- {
- int pathLen = strlen(path);
- StringPtr name = (StringPtr) fullPath;
- char * nextPath;
-
- if (path[0] == ':' || !(nextPath = strchr(path, ':'))) {
- Default();
-
- if (*path == ':')
- ++path;
- } else {
- ParamBlockRec vol;
-
- memcpy(name+1, (char *) path, *name = nextPath - (char *) path + 1);
-
- vol.volumeParam.ioNamePtr = name;
- vol.volumeParam.ioVolIndex = -1;
-
- if (error = PBGetVInfoSync(&vol))
- return;
-
- vRefNum = vol.volumeParam.ioVRefNum;
- parID = fsRtDirID;
-
- path = nextPath + 1;
-
- --*this;
- }
-
- if (error)
- return;
-
- while (*path) {
- if (*path == ':') {
- --*this;
- ++path;
-
- goto check;
- }
-
- if (nextPath = strchr(path, ':'))
- *nextPath = 0;
-
- *this += path;
-
- if (nextPath) {
- *nextPath = ':';
- path = nextPath + 1;
- } else
- break;
- check:
- if (error)
- return;
- }
-
- if (!useAlias && hasAlias)
- Resolve();
- }
-
- /* Convert a FSSpec into a full pathname. */
- char * FSp2FullPath(const FSSpec * desc)
- {
- TFileSpec spec(*desc);
-
- return spec.FullPath();
- }
-
- /* Convert a FSSpec into a relative pathname. */
- char * FSp2RelPath(const FSSpec * desc)
- {
- TFileSpec spec(*desc);
-
- return spec.RelPath();
- }
-
- /* Convert a working directory & file name into a FSSpec. */
- OSErr WD2FSSpec(short wd, ConstStr31Param name, FSSpec * desc)
- {
- TFileSpec spec(wd, name);
-
- *desc = spec;
-
- return spec.Error();
- }
-
- /* Convert a pathname into a file spec. */
- OSErr Path2FSSpec(const char * path, FSSpec * desc)
- {
- TFileSpec spec(path);
-
- *desc = spec;
-
- return spec.Error();
- }
-
- /* Return FSSpec of (vRefNum, parID) */
- OSErr FSpUp(FSSpec * desc)
- {
- TFileSpec spec(*desc);
-
- *desc = --spec;
-
- return spec.Error();
- }
-
- /* Return FSSpec of file in directory denoted by desc */
- OSErr FSpDown(FSSpec * desc, ConstStr31Param name)
- {
- TFileSpec spec(*desc);
-
- *desc = spec + name;
-
- return spec.Error();
- }
-
- /* Call GetCatInfo for file system object. */
- OSErr FSpCatInfo(const FSSpec * desc, CInfoPBRec * info)
- {
- TFileSpec spec(*desc);
-
- return spec.CatInfo(*info);
- }
-
- /* Return FSSpec of nth file in directory denoted by (vRefNum, parID) */
- OSErr FSpIndex(FSSpec * desc, short n)
- {
- TFileSpec spec(*desc);
-
- *desc = spec[n];
-
- return spec.Error();
- }
-